/*
===============================================================================
The MIT License

Copyright (c) 2009 Brian Suojanen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================================================
*/
#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif
//-----------------------------------------------------------------------------
#include "wx/filename.h"
#include "wx/textfile.h"
#include "wx/regex.h"

#include "Exception.h"
#include "Playlist.h"
//-----------------------------------------------------------------------------
Playlist::Playlist()
{
}
//-----------------------------------------------------------------------------
Playlist::~Playlist()
{
}
//-----------------------------------------------------------------------------
wxArrayString Playlist::GetFiles(const wxString& path)
{
	wxArrayString files;
	wxFileName filename(path);
	wxString ext = filename.GetExt();

	wxString formatPls = _T("pls");
	wxString formatWpl = _T("wpl");

	if (ext.IsSameAs(formatPls, false))
	{
		files = this->GetFilesFromPLS(path);
	}
	else if (ext.IsSameAs(formatWpl, false))
	{
		files = this->GetFilesFromWPL(path);
	}
	else
	{
		throw Exception(_T("Unsupported playlist file format."));
	}

	return files;
}
//-----------------------------------------------------------------------------
wxArrayString Playlist::GetFilesFromPLS(const wxString& path)
{
	wxArrayString files;
	wxTextFile file;

	if (file.Open(path))
	{
		size_t i;
		for (i = 0; i < file.GetLineCount(); i++)
		{
			wxString line = file[i];
			wxString pattern = _T("File.*=");
			wxRegEx regex;
			if (regex.Compile(pattern, wxRE_ADVANCED))
			{
				if(regex.Matches(line))
				{
					wxString match = regex.GetMatch(line);
					wxString entry = line.Mid(match.Len(), line.Len());
					// Do we need to make sure the file path is absolute?
					files.Add(entry);
				}
			}
		}
	}

	return files;
}
//-----------------------------------------------------------------------------
wxArrayString Playlist::GetFilesFromWPL(const wxString& path)
{
	wxArrayString files;
	wxTextFile file;

	// Open the file
	if (file.Open(path))
	{
		size_t i;

		// Examine each line in the file...
		for (i = 0; i < file.GetLineCount(); i++)
		{
			wxString line = file[i];

			// Windows Media Player uses XML characters (sometimes)
			wxChar* apos = wxT("&apos;");
			wxChar* apos2 = wxT("'");
			line.Replace(apos, apos2, true); // apostrophe

			wxChar* amp = wxT("&amp;");
			wxChar* amp2 = wxT("&");
			line.Replace(amp, amp2, true); // ampersand

			wxString pattern = wxT("src=\"(.*?)\"");

			wxRegEx regex;

			if (regex.Compile(pattern, wxRE_ADVANCED))
			{
				// find a match?
				if(regex.Matches(line))
				{
					// get the match
					wxString match = regex.GetMatch(line);

					// get a string minus the first 5 chars
					wxString entry = match.Right(match.Len()-5);

					// strip off the last double-quote
					entry = entry.Left(entry.Len()-1);

					// ensure the path to the song is absolute...
					entry = this->MakeAbsolute(entry, path);

					// add the file name to our string array
					files.Add(entry);
				}
			}
		}
	}

	return files;
}
//-----------------------------------------------------------------------------
wxString Playlist::MakeAbsolute(const wxString& song, const wxString& playlist)
{
	wxFileName songFileName(song);

	// If the path to the file is already absolute...
	if(songFileName.IsAbsolute(wxPATH_NATIVE)) {
		// return it.
		return song;
	}

	wxFileName playlistFileName(playlist);
	// Get the directory that the playlist is in...
	wxString playlistFolder = playlistFileName.GetPathWithSep(wxPATH_NATIVE);
	// Make the song absolute based on where it is relative to the playlist...
	songFileName.MakeAbsolute(playlistFolder, wxPATH_NATIVE);
	// Return the (hopefully) legit full path to the song. NOTE: this doesn't mean the file actually exists!
	return songFileName.GetFullPath(wxPATH_NATIVE);
}
//-----------------------------------------------------------------------------
